﻿// -----------------------------------------------------------------------
// <copyright file="PictureControl.cs" company="Image Processing Course Project">
// Created 15/10/2011
// </copyright>
// -----------------------------------------------------------------------

namespace ImageProcessing
{
    using System;
    using System.Collections.Generic;
    using System.Drawing;
    using System.IO;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;
    using ImageProcessing.Utilities;

    /// <summary>
    /// Control image processing functionalities
    /// </summary>
    public class PictureControl
    {
        /// <summary>
        /// Opens file Dialog in order to browse files for images
        /// </summary>
        /// <returns>Imaga file path</returns>
        public string BrowseImages()
        {
            string filePath = string.Empty;
            try
            {
                OpenFileDialog browser = new OpenFileDialog();
                if (browser.ShowDialog() == DialogResult.OK)
                {
                    filePath = browser.FileName;
                }
                else
                {
                }
            }
            catch (Exception e)
            {
                MessageBox.Show("Invalid file path.");
                Logger.LogException(e);
            }

            return filePath;
        }

        /// <summary>
        /// Opens images of common format e.g. bmp, gif, jpg...
        /// </summary>
        /// <param name="path">Image file path</param>
        /// <returns>Bitmap image</returns>
        public Bitmap OpenCommonFormatImage(string path)
        {
            try
            {
                Bitmap image = new Bitmap(path);
                return image;
            }
            catch (Exception e)
            {
                Logger.LogException(e);
                throw;
            }
        }

        /// <summary>
        /// Open images of format not handled in .NET e.g. P3
        /// </summary>
        /// <param name="path">Image file path</param>
        /// <returns>Bitmap image</returns>
        public Bitmap OpenOtherFormats(string path)
        {
            int width, height;
            FileStream fileStream = new FileStream(path, FileMode.Open);
            StreamReader streamReader = new StreamReader(fileStream);
            try
            {
                string nextLine, type, lastLine;
                int length = 0;
                int counter = 0;
                type = streamReader.ReadLine();
                length += type.Length;
                nextLine = streamReader.ReadLine();
                length += nextLine.Length;
                while (nextLine.StartsWith("#"))
                {
                    nextLine = streamReader.ReadLine();
                    length += nextLine.Length;
                }

                string[] dimentions = nextLine.Split(' ');
                width = int.Parse(dimentions[0]);
                height = int.Parse(dimentions[1]);
                lastLine = streamReader.ReadLine();
                length += lastLine.Length;
                string pixelValues = streamReader.ReadToEnd();
                Bitmap image = new Bitmap(width, height);

                if (type == "P3")
                {
                    char[] delimiters = new char[] { '\r', '\n', ' ' };
                    string[] values = pixelValues.Split(delimiters, StringSplitOptions.RemoveEmptyEntries);
                    for (int i = 0; i < height; i++)
                    {
                        for (int j = 0; j < width; j++)
                        {
                            image.SetPixel(j, i, Color.FromArgb(int.Parse(values[counter++]), int.Parse(values[counter++]), int.Parse(values[counter++])));
                        }
                    }

                    return image;
                }
                else
                    if (type == "P6")
                    {
                        fileStream.Position = length + 1;
                        for (int i = 0; i < height; i++)
                        {
                            for (int j = 0; j < width; j++)
                            {
                                image.SetPixel(j, i, Color.FromArgb(fileStream.ReadByte(), fileStream.ReadByte(), fileStream.ReadByte()));
                            }
                        }

                        return image;
                    }
                    else
                    {
                        return null;
                    }
            }
            catch (Exception e)
            {
                Logger.LogException(e);
                throw;
            }
            finally
            {
                fileStream.Close();
                streamReader.Close();
            }
        }

        /// <summary>
        /// Checks whether the image is common format or not and calls the appropriate function accordingly
        /// </summary>
        /// <returns>Bitmap Image</returns>
        public Bitmap OpenImage()
        {
            try
            {
                string path = this.BrowseImages();
                if (path != string.Empty)
                {
                    string[] extention = path.Split('.');
                    if (extention[1].ToLower() == "ppm")
                    {
                        return this.OpenOtherFormats(path);
                    }
                    else
                    {
                        return this.OpenCommonFormatImage(path);
                    }
                }
                else
                {
                    return null;
                }
            }
            catch (Exception e)
            {
                Logger.LogException(e);
                throw;
            }
        }
    }
}